﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Dyd.BaseService.Monitor.Collect.CollectTasks;
using Dyd.BaseService.Monitor.Collect.Tool;
using Dyd.BaseService.Monitor.Core;
using Dyd.BaseService.Monitor.Domain.Cluster.Dal;
using Dyd.BaseService.Monitor.Domain.Cluster.Model;
using XXF.BaseService.Monitor.SystemRuntime;
using XXF.ProjectTool;
using XXF.Serialization;
using XXF.Extensions;

namespace Dyd.BaseService.Monitor.Collect.BackgroundTasks
{

    /// <summary>
    /// 服务器的当前状态监控，一般包括网络、磁盘、内存、cpu等，根据监控的配置项，这些可能会有变化
    /// 这些信息会保存在当前服务的的状态表里，服务器的快照就是从该表里定期取的状态信息。
    /// </summary>
    public class MonitorCollectBackgroundTask : BaseBackgroundTask
    {
        /// .net内置性能记数器，如 IIS请求，网络流量
        List<PerformanceCounterCollectTask> pcounts = new List<PerformanceCounterCollectTask>();
        //自定义的性能监控 磁盘
        DiskInfoCollectTask dct = null;
        //自定义的性能监控 内存
        MemoryPercentCollectTask mct = null;
        //当前可用的自定义性能监控
        List<BaseCollectTask> customtasks = new List<BaseCollectTask>();

        public override void Start()
        {
            try
            {
                //监控间隔
                this.TimeSleep = GlobalConfig.MonitorCollectBackgroundTaskSleepTime * 1000;
                dct = new DiskInfoCollectTask();
                mct = new MemoryPercentCollectTask();
                customtasks.Add(dct); customtasks.Add(mct);
                if (!string.IsNullOrWhiteSpace(GlobalConfig.ClusterModel.monitorcollectconfigjson))
                {
                    var collectconfigs = new XXF.Serialization.JsonHelper().Deserialize<List<Core.CollectConfig>>(GlobalConfig.ClusterModel.monitorcollectconfigjson);
                    //当前服务器的监控配置，要监控的指数，包括内置和自定义，用类型来区分，对于系统（或叫内置）的监控，
                    //这里做了一层封装，已便适合本功能使用。
                    foreach (var config in collectconfigs)
                    {
                        if (config.CollectType == CollectType.System)//系统内置的
                            pcounts.Add(new PerformanceCounterCollectTask(config));
                        else
                        {
                            foreach (var ct in customtasks)
                            {
                                //自定义的使用名定来查找
                                if (config.CollectName == ct.Name)
                                {
                                    ct.IsCollect = true;
                                }
                            }
                        }
                    }
                }
                base.Start();//基类的开始
            }
            catch (Exception exp)
            {
                LogHelper.Error(string.Format("服务器[id:{0}] MonitorCollectBackgroundTask 初始化错误",GlobalConfig.ServerIP.NullToEmpty()), exp);
            }
        }
        protected override void Run()
        {
            //是否开启 监控
            if (GlobalConfig.ClusterModel.ifmonitor == false)
                return;
            //采集到的数据记录
            List<ClusterMonitorInfo> cmis = new List<ClusterMonitorInfo>();
            //对系统的计数据进行记录收集
            foreach (var p in pcounts)
            {
                var c = p.Collect();
                cmis.Add(new ClusterMonitorInfo(p.Name, c.ToString("F2"), (double)c));
            }
            //自定义的磁盘是否开启
            if (dct.IsCollect == true)
            {
                string msg = ""; double minfreespace = 1000000;
                foreach (var d in dct.Collect())
                {
                    minfreespace = Math.Min(minfreespace, d.FreeSpace);
                    msg += string.Format("[{0}]:{1}(G)/{2}(G)\r\n", d.Name, d.FreeSpace.ToString("F2"),d.TotalSpace.ToString("F2"));
                }
                cmis.Add(new ClusterMonitorInfo(dct.Name, msg, minfreespace));
            }

            //自定义的内存是否开启
            if (mct.IsCollect == true)
            {
                var mper = mct.Collect();
                cmis.Add(new ClusterMonitorInfo(mct.Name, string.Format("剩余/总量:{0}(M)/{1}(M) 已用:{2}%",ConvertHelper.ByteToM(mper.AvailablePhysicalMemory).ToString("F2"),ConvertHelper.ByteToM(mper.TotalPhysicalMemory).ToString("F2"), mper.UserdPercent), mper.UserdPercent));
            }

            //将收集到的信息添加到该服务器的状态表中。
            SqlHelper.ExcuteSql(DbShardingHelper.GetDataBase(GlobalConfig.DataBaseConfigModels.Select(c1 => (dynamic)c1).ToList(), DataBaseType.Cluster), (c) =>
            {

                tb_cluster_monitorinfo_dal dal = new tb_cluster_monitorinfo_dal();
                //更新状态信息，原则上不会出现Add的时候。
                dal.AddOrUpdate(c, new tb_cluster_monitorinfo_model() { lastupdatetime = c.GetServerDate(), serverid = GlobalConfig.ClusterModel.id, monitorinfojson = new JsonHelper().Serializer(cmis) });
            });
        }
    }
}
